﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Legazpi.Payroll.BusinessLogic.Services.Interfaces;
using Legazpi.Payroll.DataAccess.Repositories;
using System.Data.Entity;
using Legazpi.Payroll.DataAccess.DataObjects;
using Legazpi.Payroll.DataAccess.Base;

namespace Legazpi.Payroll.BusinessLogic.Services
{
   public class PayrollDateService :IPayrollDateService
    {
        #region Fields

        private DbContext _dbContext;
        private IPayrollDateRepository _payrollDateRepository;
        private IDatabaseFactory _dbFactory;
        #endregion

        #region ctor

        public PayrollDateService()
            : this(new DatabaseFactory())
        {

        }

        public PayrollDateService(IDatabaseFactory dbFactory)
        {
            if (dbFactory == null) throw new ArgumentNullException("dbFactory");
            _dbFactory = dbFactory;
            DbContext = dbFactory.Get();
        }

        private DbContext DbContext
        {
            get { return _dbContext; }
            set
            {
                _dbContext = value;
                _payrollDateRepository = new PayrollDateRepository(_dbContext);
            }
        }

        #endregion

        public PayrollDate GetById(int id)
        {
            return _payrollDateRepository.GetById(id);
        }

        public IEnumerable<PayrollDate> GetAll()
        {
            return _payrollDateRepository.GetAll();
        }

        public IEnumerable<PayrollDate> Get(int multiplier, int count)
        {
            throw new NotImplementedException();
        }

        public IEnumerable<PayrollDate> Get()
        {
            throw new NotImplementedException();
        }

        public bool IsValidPaydate(DateTime payDate)
        {            
            if (payDate.Day != 1)
            {
                if (payDate.Day != 16)
                    return false;
            }
            return true;
        }

        public PayrollDate GetPreviousPayroll()
        {
            return _payrollDateRepository.GetQuery()
                .OrderByDescending(x => x.Id)
                .Take(1)
                .FirstOrDefault();
            
        }
        public PayrollDate GetActivePayroll()
        {
            return _payrollDateRepository.GetQuery()
                .Where(x => x.Active == true)
                .OrderByDescending(x => x.Id)
                .Take(1)
                .FirstOrDefault();
        }        
        public void Add(PayrollDate payrollDate)
        {            
            if (!IsValidPaydate(payrollDate.Paydate))
                throw new InvalidProgramException("Paydate day must start with 1 or 16");

            //var lastDayOfMonth = DateTime.DaysInMonth(payrollDate.Paydate.Year, payrollDate.Paydate.Month);
            //payrollDate.Startdate = payrollDate.Paydate;
            //payrollDate.Enddate= payrollDate.Paydate.Day == 1 ? 
            ////    new DateTime(payrollDate.Paydate.Year,payrollDate.Paydate.Month,15) :
            //    new DateTime(payrollDate.Paydate.Year, payrollDate.Paydate.Month, lastDayOfMonth);
                                    
            _payrollDateRepository.Add(payrollDate);
        }

        public void Update(PayrollDate payrollDate)
        {
            if (!IsValidPaydate(payrollDate.Paydate))
                throw new InvalidProgramException("Paydate day must start with 1 or 16");

            _payrollDateRepository.Update(payrollDate);
        }

        public void Delete(int id)
        {
            var payrollDate = GetById(id);
            if (payrollDate != null)
                _payrollDateRepository.Delete(payrollDate);
        }

        public bool Save()
        {
            string message;
            _payrollDateRepository.Save(out message);
            return message == "Saved";
        }


        public void SetActive(int id)
        {
            _dbContext.Database.ExecuteSqlCommand("UPDATE payrolldate set Active='false' where id <> " + id);
            this.Save();
            //var payrollDate = GetById(id);
            //_payrollDateRepository.GetQuery()
            //   .Where(x => x.Active == true && x.Id != id)
            //   .ToList()
            //   .ForEach(a =>  a.Active = false);
            var payrollDate = GetById(id);
            if (payrollDate != null)
            {
                payrollDate.Active = true;
                _payrollDateRepository.Update(payrollDate);
            }
                
            
        }
    }
}
